package com.xjrsoft.module.erpModel.caseErpPurchase.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.module.erpModel.caseErpPurchase.entity.CaseErpApply;
import com.xjrsoft.module.erpModel.caseErpPurchase.entity.CaseErpApplyDetail;
import com.xjrsoft.module.erpModel.caseErpPurchase.entity.CaseErpPurchase;
import com.xjrsoft.module.erpModel.caseErpPurchase.mapper.CaseErpApplyDetailMapper;
import com.xjrsoft.module.erpModel.caseErpPurchase.mapper.CaseErpApplyMapper;
import com.xjrsoft.module.erpModel.caseErpPurchase.service.ICaseErpPurchaseApplyDetailService;
import com.xjrsoft.module.erpModel.caseErpPurchase.service.ICaseErpPurchaseApplyService;
import com.xjrsoft.module.erpModel.caseErpPurchase.service.ICaseErpPurchaseService;
import com.xjrsoft.module.erpModel.caseErpPurchase.vo.CaseErpApplyPageVo;
import com.xjrsoft.module.erpModel.caseErpPurchase.vo.CaseErpApplyVo;
import com.xjrsoft.module.organization.entity.Department;
import com.xjrsoft.module.organization.entity.User;
import com.xjrsoft.module.system.entity.DictionaryDetail;
import com.xjrsoft.module.system.service.IDictionarydetailService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @title: service
* @Author 管理员
* @Date: 2023-07-20
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class CaseErpPurchaseApplyServiceImpl extends MPJBaseServiceImpl<CaseErpApplyMapper, CaseErpApply> implements ICaseErpPurchaseApplyService {
    private final CaseErpApplyMapper purchasingApplyCaseErpApplyMapper;

    private final CaseErpApplyDetailMapper purchasingApplyCaseErpApplyDetailMapper;

    private  RedisUtil redisUtil;

    private final ICaseErpPurchaseApplyDetailService caseErpPurchaseApplyDetailService;

    private final ICaseErpPurchaseService caseErpPurchaseService;

    private final IDictionarydetailService dictionarydetailService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(CaseErpApply caseErpApply) {
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY,new TypeReference<List<Department>>() {
        });
        if (ObjectUtil.isNotEmpty(caseErpApply.getApplyDepId())){
            Department department = departmentList.stream().filter(x -> x.getId().equals(caseErpApply.getApplyDepId())).findFirst().orElse(new Department());
            if (StrUtil.isNotBlank(department.getName())){
                caseErpApply.setApplyDepName(department.getName());
            }
        }
        if (StrUtil.isNotBlank(caseErpApply.getApplyUserIds())){
            String allUserIdStr = StrUtil.join(StringPool.COMMA, caseErpApply.getApplyUserIds());
            List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            List<String> names = userList.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
            caseErpApply.setApplyUserNames(StrUtil.join(StringPool.COMMA,names));
        }
        purchasingApplyCaseErpApplyMapper.insert(caseErpApply);
        for (CaseErpApplyDetail caseErpApplyDetail : caseErpApply.getCaseErpApplyDetailList()) {
            caseErpApplyDetail.setApplyId(caseErpApply.getId());
            purchasingApplyCaseErpApplyDetailMapper.insert(caseErpApplyDetail);
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(CaseErpApply caseErpApply) {
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY,new TypeReference<List<Department>>() {
        });
        if (ObjectUtil.isNotEmpty(caseErpApply.getApplyDepId())){
            Department department = departmentList.stream().filter(x -> x.getId().equals(caseErpApply.getApplyDepId())).findFirst().orElse(new Department());
            if (StrUtil.isNotBlank(department.getName())){
                caseErpApply.setApplyDepName(department.getName());
            }
        }
        if (StrUtil.isNotBlank(caseErpApply.getApplyUserIds())){
            String allUserIdStr = StrUtil.join(StringPool.COMMA, caseErpApply.getApplyUserIds());
            List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            List<String> names = userList.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
            caseErpApply.setApplyUserNames(StrUtil.join(StringPool.COMMA,names));
        }
        purchasingApplyCaseErpApplyMapper.updateById(caseErpApply);
        //********************************* CaseErpApplyDetail  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<CaseErpApplyDetail> caseErpApplyDetailList = purchasingApplyCaseErpApplyDetailMapper.selectList(Wrappers.lambdaQuery(CaseErpApplyDetail.class).eq(CaseErpApplyDetail::getApplyId, caseErpApply.getId()).select(CaseErpApplyDetail::getId));
            List<Long> caseErpApplyDetailIds = caseErpApplyDetailList.stream().map(CaseErpApplyDetail::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> caseErpApplyDetailOldIds = caseErpApply.getCaseErpApplyDetailList().stream().map(CaseErpApplyDetail::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> caseErpApplyDetailRemoveIds = caseErpApplyDetailIds.stream().filter(item -> !caseErpApplyDetailOldIds.contains(item)).collect(Collectors.toList());

            for (CaseErpApplyDetail caseErpApplyDetail : caseErpApply.getCaseErpApplyDetailList()) {
                //如果不等于空则修改
                if (caseErpApplyDetail.getId() != null) {
                    purchasingApplyCaseErpApplyDetailMapper.updateById(caseErpApplyDetail);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    caseErpApplyDetail.setApplyId(caseErpApply.getId());
                    purchasingApplyCaseErpApplyDetailMapper.insert(caseErpApplyDetail);
                }
            }
            //已经不存在的id 删除
            if(caseErpApplyDetailRemoveIds.size() > 0){
                purchasingApplyCaseErpApplyDetailMapper.deleteBatchIds(caseErpApplyDetailRemoveIds);
            }
        }
        //********************************* CaseErpApplyDetail  增删改  结束 *******************************************/

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        purchasingApplyCaseErpApplyMapper.deleteBatchIds(ids);
        purchasingApplyCaseErpApplyDetailMapper.delete(Wrappers.lambdaQuery(CaseErpApplyDetail.class).in(CaseErpApplyDetail::getApplyId, ids));

        return true;
    }

    @Override
    public List<CaseErpApplyPageVo> convert(List<CaseErpApplyPageVo> caseErpApplyPageVos) {
        List<CaseErpApplyDetail> applyDetailList = caseErpPurchaseApplyDetailService.list();
        List<CaseErpPurchase> purchaseList = caseErpPurchaseService.list();
        List<Department> deptList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
        });
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        List<DictionaryDetail> dictionaryDetailList = dictionarydetailService.list();
        for (CaseErpApplyPageVo vo : caseErpApplyPageVos) {
            if (StrUtil.isNotBlank(vo.getApplyUserIds())){
                String allUserIdStr = StrUtil.join(StringPool.COMMA, vo.getApplyUserIds());
                List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
                List<String> names = userList.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
                vo.setApplyUserName(StrUtil.join(StringPool.COMMA,names));
            }
            if (ObjectUtil.isNotEmpty(vo.getApplyDepId())){
                Department department = deptList.stream().filter(x -> x.getId().equals(vo.getApplyDepId())).findFirst().orElse(new Department());
                if (StrUtil.isNotBlank(department.getName())){
                    vo.setApplyDepName(department.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(vo.getRelatedProject())){
                DictionaryDetail dictionaryDetail = dictionaryDetailList.stream().filter(x -> x.getId().equals(vo.getRelatedProject())).findFirst().orElse(new DictionaryDetail());
                if (StrUtil.isNotBlank(dictionaryDetail.getName())){
                    vo.setRelatedProjectName(dictionaryDetail.getName());
                }
            }
            StringBuilder detailStr = new StringBuilder();
            for (CaseErpApplyDetail applyDetail : applyDetailList) {
                if (ObjectUtil.equals(vo.getId(), applyDetail.getApplyId())) {
                    detailStr.append(StringPool.COMMA);
                    detailStr.append(applyDetail.getName());
                    detailStr.append(StringPool.COLON + StringPool.SPACE);
                    detailStr.append(String.format("%.0f", applyDetail.getCount()));
                }
            }
            if (detailStr.length() > 0) {
                detailStr.delete(0, 1);
            }
            vo.setApplyDetail(detailStr.toString());
            for (CaseErpPurchase purchase : purchaseList) {
                if (ObjectUtil.equals(purchase.getApplyId(), vo.getId())) {
                    vo.setPurchaseStatus(1);
                    break;
                }
                vo.setPurchaseStatus(0);
            }
        }
        return caseErpApplyPageVos;
    }

    @Override
    public CaseErpApplyVo convertInfo(CaseErpApplyVo caseErpApplyVo) {
        List<Department> deptList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
        });
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        List<DictionaryDetail> dictionaryDetailList = dictionarydetailService.list();
        if (StrUtil.isNotBlank(caseErpApplyVo.getApplyUserIds())){
            String allUserIdStr = StrUtil.join(StringPool.COMMA, caseErpApplyVo.getApplyUserIds());
            List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            List<String> names = userList.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
            caseErpApplyVo.setApplyUserNames(StrUtil.join(StringPool.COMMA,names));
        }
        if (ObjectUtil.isNotEmpty(caseErpApplyVo.getApplyDepId())){
            Department department = deptList.stream().filter(x -> x.getId().equals(caseErpApplyVo.getApplyDepId())).findFirst().orElse(new Department());
            if (StrUtil.isNotBlank(department.getName())){
                caseErpApplyVo.setApplyDepName(department.getName());
            }
        }
        if (ObjectUtil.isNotEmpty(caseErpApplyVo.getRelatedProject())){
            DictionaryDetail dictionaryDetail = dictionaryDetailList.stream().filter(x -> x.getId().equals(caseErpApplyVo.getRelatedProject())).findFirst().orElse(new DictionaryDetail());
            if (StrUtil.isNotBlank(dictionaryDetail.getName())){
                caseErpApplyVo.setRelatedProjectName(dictionaryDetail.getName());
            }
        }
        return caseErpApplyVo;
    }
}
